package libra.sentinelTest;

import java.util.List;

import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.FileWritableDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSONObject;

public class InitRules implements InitFunc{
	
	String ruleDir = "C:/Users/libra/OneDrive/UserSysConfig/ForTest";
	String flowRulePath = ruleDir + "/sentiel-test-flow-rule.json";
	String degradeRulePath = ruleDir + "/sentiel-test-degrade-rule.json";
	String systemRulePath = ruleDir + "/sentiel-test-system-rule.json";
	String authorityRulePath = ruleDir + "/sentiel-test-authority-rule.json";
	String paramFlowRulePath = ruleDir + "/sentiel-test-param-flow-rule.json";
	
    public void init() throws Exception {
        /*
         * 流控规则
         */
        ReadableDataSource<String, List<FlowRule>> flowRuleRDS = 
        	new FileRefreshableDataSource<>( flowRulePath, new ReadConverter<FlowRule>(FlowRule.class) );
        // 将可读数据源注册至FlowRuleManager
        // 这样当规则文件发生变化时，就会更新规则到内存
        FlowRuleManager.register2Property(flowRuleRDS.getProperty());
        
        WritableDataSource<List<FlowRule>> flowRuleWDS = 
        	new FileWritableDataSource<>( flowRulePath, new WriteConverter<FlowRule>() );
        // 将可写数据源注册至transport模块的WritableDataSourceRegistry中
        // 这样收到控制台推送的规则时，Sentinel会先更新到内存，然后将规则写入到文件中
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);

        
        /*
         * 降级规则
         */
        ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = 
        	new FileRefreshableDataSource<>( degradeRulePath, new ReadConverter<DegradeRule>(DegradeRule.class) );
        DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
        
        WritableDataSource<List<DegradeRule>> degradeRuleWDS = 
        	new FileWritableDataSource<>( degradeRulePath, new WriteConverter<DegradeRule>() );
        WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);

        
        /*
         * 系统规则
         */
        ReadableDataSource<String, List<SystemRule>> systemRuleRDS = 
        	new FileRefreshableDataSource<>( systemRulePath, new ReadConverter<SystemRule>(SystemRule.class) );
        SystemRuleManager.register2Property(systemRuleRDS.getProperty());
        
        WritableDataSource<List<SystemRule>> systemRuleWDS = 
        	new FileWritableDataSource<>( systemRulePath, new WriteConverter<SystemRule>() );
        WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);

        
        /*
         * 授权规则
         */
        ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = 
        	new FileRefreshableDataSource<>( authorityRulePath, new ReadConverter<AuthorityRule>(AuthorityRule.class) );
        AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
        
        WritableDataSource<List<AuthorityRule>> authorityRuleWDS = 
        	new FileWritableDataSource<>( authorityRulePath, new WriteConverter<AuthorityRule>() );
        WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);

        
        /*
         * 热点参数规则
         */
        ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS =
    		new FileRefreshableDataSource<>( paramFlowRulePath, new ReadConverter<ParamFlowRule>(ParamFlowRule.class) );
        ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
        
        WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = 
        	new FileWritableDataSource<>( paramFlowRulePath, new WriteConverter<ParamFlowRule>() );
        ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
    }
}
class ReadConverter <T> implements Converter<String, List<T>> {
	private Class<T> clazzT;
	public ReadConverter(Class<T> clazzT) {
		super();
		this.clazzT = clazzT;
	}
	@Override
	public List<T> convert(String source) {
		try {
			System.out.println("读取：" + source);
			return JSONObject.parseArray(source, clazzT);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return List.of();
	}
}
class WriteConverter <T> implements Converter<List<T>, String> {
	@Override
	public String convert(List<T> source) {
		System.out.println("写入：" + source);
		return JSONObject.toJSONString(source);
	}
}